<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <script src="./node_modules/vue/dist/vue.js"></script>
    <title>Vue-demo</title>
</head>
<body>
    <div id="app">{{msg}}</div>
<!-- 
    1、app.msg修改数据，vue内部是如何监听msg数据改变；
        Object.defineProperty -> 监听对象属性的改变

    2、当数据发声改变，vue内部是如何知道要通知哪些人，界面发生刷新 
        *发布订阅者模式
-->
</body>
    <script>
        // 1、通过defineProperty可以set监听到值发生了改变
        const obj={
            msg:'哈哈哈',
            name:'whe'
        }
        Object.keys(obj).forEach(key=>{
            let value=obj[key]
            Object.defineProperty(obj,key,{
                set(newValue){
                    console.log("发生了值改变，这里监听到"+key+"改变");
                    //得通知用的页面值发生了改变
                    //根据解析的html获取到哪些页面有用到属性
                    value=newValue
                },
                get(){
                    console.log("获取"+ key+ '对应的值');
                    // 用 的页面会调用get，知道什么地方用到了 -> update
                    return value
                }
            })
        })
        // 发布订阅者模式
        class Dep{
            constructor(){
                this.subs=[] //订阅
            }
            addSub(wather){
                this.subs.push(wather)
            }
            //通知
            notofy(){
                this.subs.forEach(item=>{
                    item.update()
                })
            }
        }
        class Watch{
            constructor(name){
                this.name=name
            }
            update() {
                console.log(this.name+'发生了update');
            }
        }
        const dep=new Dep()
        const w1=new Watch("张三");
        dep.addSub(w1);
        const w2=new Watch("李四");
        dep.addSub(w2);

        const vm = new Vue({
            el: "#app",
            data: {
                msg:"hahaha"
            },
            methods: {},
        });
    </script>
</html>